package test;

import grammar.Assembly;
import geometry.Box;
import geometry.ComboBox;
import geometry.Geometry;
import grammar.Product;
import grammar.Design;
import grammar.InstantiationInput;
import grammar.ModificationRule;
import grammar.Rule;
import graph.GNode;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import constraint.Constraint;
import constraint.Variable;
import constraint.VariableType; 

public class PoleBarn {
	
	//THESE DEFINE THE WORKING MATERIALS FOR THE POLE BARN
	static float postspacing=0;
	
	static float slabwidth     = 100;
    static float slablength    = 100;
    static float slabthickness = 1;
	
	static float postlength   = 25;
	static float postwidth    =  1;
	static float postheight   =  1;
	
	static float bendangle    = 36;
	static float bendlength   = 5;
	static float bendwidth    = postwidth +1 ;     
	static float bendheight   = postheight + 1;
	
	static float anchorlength = 5;
	static float anchorwidth  = postwidth +1 ;     
	static float anchorheight = postheight + 1;
	
	public static void postspacer(float spacer){
		postspacing = spacer;
	}
	
public static Design buildInitialBarn() {
    Design design = new Design();
    Product barn = design.setProduct("PRODUCT");
    Assembly assembly = design.addAssembly("ASSEMBLY");
    Box slab = design.addBox(assembly,100,1,100,"SLAB");
    slab.addLabel("ACTIVE");
    return design;
}
    
    public static Rule anchortoground() {
        //LHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design lhs = new Design();
        Product barn = lhs.setProduct("PRODUCT");
        Assembly assembly = lhs.addAssembly("ASSEMBLY");
        Box slab = lhs.addBox(assembly,slabwidth,slabthickness,slablength,"SLAB");
        slab.addLabel("ACTIVE");
        

        //RHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design rhs = new Design();
        rhs.setProduct(barn);
        rhs.addGeometry(assembly,slab);
        Box anchor = rhs.addBox(assembly,anchorwidth,anchorlength,anchorheight,"ANCHOR");
        anchor.translateBy(0, slabthickness, postspacing);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        InstantiationInput input = new InstantiationInput();
        
        Rule rule = new ModificationRule(lhs, rhs, input, new GNode[]{});
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Map <Geometry, String[]> labelsToRemove = new HashMap<Geometry, String[]>();
        Map <Geometry, String[]> labelsToAdd = new HashMap<Geometry, String[]>();
        labelsToRemove.put(slab, new String[]{"ACTIVE"});
        labelsToAdd.put(anchor, new String[]{"ACTIVE"});
        
        rule.setLabelChanges(labelsToRemove, labelsToAdd);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        //Input variables
        return rule;    
    }

    public static Rule anchortopost() {
        //LHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    	Design lhs = new Design();
        Product barn = lhs.setProduct("PRODUCT");
        Assembly assembly = lhs.addAssembly("ASSEMBLY");
        Box post = lhs.addBox(assembly,postwidth,postlength,postheight,"POST");
        post.addLabel("ACTIVE");
        //RHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design rhs = new Design();
        rhs.setProduct(barn);
        rhs.addGeometry(assembly,post);
        Box anchor = rhs.addBox(assembly,anchorwidth,anchorlength,anchorheight,"ANCHOR");
        anchor.translateBy(-(anchorwidth-postwidth)/2, postlength, -(anchorheight-postheight)/2);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        InstantiationInput input = new InstantiationInput();
        
        Rule rule = new ModificationRule(lhs, rhs, input, new GNode[]{});
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Map <Geometry, String[]> labelsToRemove = new HashMap<Geometry, String[]>();
        Map <Geometry, String[]> labelsToAdd = new HashMap<Geometry, String[]>();
        
        labelsToRemove.put(post, new String[]{"ACTIVE"});
        labelsToAdd.put(anchor, new String[]{"ACTIVE"});
        rule.setLabelChanges(labelsToRemove, labelsToAdd);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        //Input variables
        return rule;    
    }
    
    public static Rule posttoanchor() {
        //LHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    	Design lhs = new Design();
        Product barn = lhs.setProduct("PRODUCT");
        Assembly assembly = lhs.addAssembly("ASSEMBLY");
        Box anchor = lhs.addBox(assembly,anchorwidth,anchorlength,anchorheight,"ANCHOR");
        anchor.addLabel("ACTIVE");

        //RHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design rhs = new Design();
        rhs.setProduct(barn);
        rhs.addGeometry(assembly,anchor);
        Box post = rhs.addBox(assembly,postwidth,postlength,postheight,"POST");
        post.translateBy((anchorwidth-postwidth)/2, anchorlength, (anchorheight-postheight)/2);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        InstantiationInput input = new InstantiationInput();
        
        Rule rule = new ModificationRule(lhs, rhs, input, new GNode[]{});
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Map <Geometry, String[]> labelsToRemove = new HashMap<Geometry, String[]>();
        Map <Geometry, String[]> labelsToAdd = new HashMap<Geometry, String[]>();
        
        labelsToRemove.put(anchor, new String[]{"ACTIVE"});
        labelsToAdd.put(post, new String[]{"ACTIVE"});
        rule.setLabelChanges(labelsToRemove, labelsToAdd);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        //Input variables
        return rule;    
    }
    

    
    public static Rule bendtopost() {
        //LHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design lhs = new Design();
        Product barn = lhs.setProduct("PRODUCT");
        Assembly assembly = lhs.addAssembly("ASSEMBLY");
        Box post = lhs.addBox(assembly,1,20,1,"POST");     //variable name doesn't have to be unique  "unique name"  should be
        post.addLabel("ACTIVE");
        //RHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design rhs = new Design();
        rhs.setProduct(barn);
        rhs.addGeometry(assembly,post);
        Box bend = rhs.addBox(assembly,bendwidth,bendlength,bendheight,"BEND");
        bend.translateBy(-(bendwidth-postwidth)/2, postlength, -(bendwidth-postwidth)/2);
        bend.rotate(0, 0, -bendangle/2);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        InstantiationInput input = new InstantiationInput();
        
        Rule rule = new ModificationRule(lhs, rhs, input, new GNode[]{});
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Map <Geometry, String[]> labelsToRemove = new HashMap<Geometry, String[]>();
        Map <Geometry, String[]> labelsToAdd = new HashMap<Geometry, String[]>();
        labelsToRemove.put(post, new String[]{"ACTIVE"});
        labelsToAdd.put(bend, new String[]{"ACTIVE"});
        rule.setLabelChanges(labelsToRemove, labelsToAdd);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        //Input variables
        return rule;    
    }
    
    public static Rule posttobend() {
        //LHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design lhs = new Design();
        Product barn = lhs.setProduct("PRODUCT");
        Assembly assembly = lhs.addAssembly("ASSEMBLY");
        Box bend = lhs.addBox(assembly,bendwidth,bendlength,bendheight,"BEND");
        bend.addLabel("ACTIVE");
        //RHS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Design rhs = new Design();
        rhs.setProduct(barn);
        rhs.addGeometry(assembly,bend);
        Box post = rhs.addBox(assembly,postwidth,postlength,postheight,"POST");
        post.translateBy((bendwidth-postwidth)/2, bendlength, (bendwidth-postwidth)/2);
        post.rotate(0, 0, -bendangle/2);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        InstantiationInput input = new InstantiationInput();
        
        Rule rule = new ModificationRule(lhs, rhs, input, new GNode[]{});
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Map <Geometry, String[]> labelsToRemove = new HashMap<Geometry, String[]>();
        Map <Geometry, String[]> labelsToAdd = new HashMap<Geometry, String[]>();
        labelsToRemove.put(bend, new String[]{"ACTIVE"});
        labelsToAdd.put(post, new String[]{"ACTIVE"});
        rule.setLabelChanges(labelsToRemove, labelsToAdd);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        //Input variables
        return rule;    
    }

	public static Rule profilecopy() {
		// TODO Auto-generated method stub
		return null;
	}

}
    